import * as insVue from 'vue'
import * as monaco from 'monaco-editor'

import dayjs from 'dayjs'
import { cloneDeep } from 'lodash-es'
import { bwUtils as _bwUtils } from '@bitwit/utils'

import BwMonacoEditor from '@/utils/monacoEditor'
import { useComDesignStoreWithOut } from '@/store'
import { ref, unref, toRaw, nextTick, watch, onBeforeUnmount } from 'vue'

import type { BwCallFunctionEngineOptionsModel } from './model'
import type {
  SysProcAppPreviewFlowInput,
  SysProcInstanceAppGetApplyTaskInput,
  SysProcInstanceAppGetCarbonTaskInput as SysCarbonTaskInput,
  SysProcInstanceAppGetApproveTaskInput as SysApproveTaskInput,
  SysProcInstanceAppDeliverApproveTaskInput as SysDeliverApproveTaskInput,
  SysProcInstanceAppAddSignApproveTaskInput as SysAddSignApproveTaskInput,
  SysProcInstanceAppTakebackAddSignApproveTaskInput as SysTakebackAddSignApproveTaskInput,
  SysTokenAppInfoOutput,
} from '@bitwit/tenantapi'
import { api, useAxiosResponse } from '/@/api'
import { bwUtils as bwUtilsGlobal } from '/@/utils/main'

export function useLogicCode(emit) {
  const bwMonacoEditor = new BwMonacoEditor()
  const designStore = useComDesignStoreWithOut()

  const codeEdit = ref()
  const curValue = ref<string>()
  const isMax = ref<boolean>(false)
  const curEditor = ref<monaco.editor.IStandaloneCodeEditor | undefined>()

  const onSize = (is: boolean) => {
    isMax.value = is
  }

  const onCloseCode = () => emit('close')

  /** 获取当前逻辑信息 */
  const getValue = (): string => {
    let value = ''
    const curEdit = unref(curEditor)
    if (curEdit) {
      value = toRaw(curEdit).getValue()
    }
    return value
  }

  const initMonacoEditor = () => {
    const curLogicCode = designStore.getSetupLogic

    const bwParams = getInsBwUtils(insVue)
    const tips = `const bwUtils = {${Object.keys(bwParams).join(',')}} `

    curValue.value = curLogicCode
    curEditor.value = bwMonacoEditor.create({
      domElement: codeEdit.value,
      tips: tips,
      menus: undefined,
      snippets: undefined,
      options: {
        value: curLogicCode,
        language: 'typescript',
      },
    })

    /** 监听编辑器内容变化 */
    const curEdit = unref(curEditor)
    if (curEdit) {
      curEdit.onDidChangeCursorPosition((e) => {
        if (curEdit) {
          let readOnly = false
          if (e.position.lineNumber < 2) {
            readOnly = true
          }
          toRaw(curEdit).updateOptions({
            readOnly: readOnly,
          })
        }
      })

      curEdit.onDidChangeModelContent(() => {
        try {
          const curText = getValue()
          if (curText) {
            curValue.value = curText
            designStore.setDesignSetupLogic(curText)
          }
        } catch (error) {
          console.warn('编辑器报错')
        }
      })
    }
  }

  onBeforeUnmount(() => {
    /** 编辑器关闭前保存内容 */
    designStore.setDesignSetupLogic(unref(curValue) ?? '')
    bwMonacoEditor.dispose()
  })

  watch(
    () => designStore.curFrontType,
    () => {
      nextTick(() => {
        initMonacoEditor()
      })
    },
    { deep: true, immediate: true }
  )

  return { isMax, codeEdit, onSize, onCloseCode }
}

export function getInsBwUtils(options: Record<string, any>) {
  const bwUtils = {
    /** 页面路由参数 */
    params: {},

    cloneDeep,

    dayjs: dayjs,
    flatArray: _bwUtils.flatArray,
    formatToDate: _bwUtils.formatToDate,
    /** 登录 获取token */
    getSysToken(params: {
      loginId: string
      password: string
      category: string
    }) {
      const { loginId, password, category = 'builtIn' } = params
      return new Promise((resolve, reject) => {
        api
          .apiSysTokenGetGet(loginId, password, category)
          .then((res) => {
            const resData = useAxiosResponse<SysTokenAppInfoOutput>(res)
            resolve(resData)
          })
          .catch((err) => {
            reject(err)
          })
      })
    },
    setCookie: bwUtilsGlobal.setCookie,
    getCookie: bwUtilsGlobal.getCookie,
    delCookie: bwUtilsGlobal.delCookie,

    /** 设置Token */
    setToken(_token: string) {},

    /** 获取Token */
    getToken() {},

    /** 刷新token */
    onRefreshToken() {},

    /** 设置存储空间 -- 值 */
    setStorageInfo(_key: string, _value: any) {},

    /** 获取存储空间信息  */
    getStorageInfo() {},

    /** 获取存储空间信息  */
    getStorageValueToKey(_key: string, _defaultValue?: any) {},

    /** 函数引擎 调度 */
    callFunctionEngine(
      _params: BwCallFunctionEngineOptionsModel
    ): Promise<any> {
      return new Promise<any>((resolve) => {
        resolve({})
      })
    },

    /** 获取地址数据 */
    getAddrSource() {
      return []
    },

    /** 获取流程步骤预览流向 */
    getPreviewFolwProc(data: SysProcAppPreviewFlowInput) {
      return new Promise<any>((resolve, reject) => {
        data ? resolve({}) : reject()
      })
    },

    /** 获取流程步骤申请页面信息 */
    getFlowPrcoStartPageInfo(procId: string): Promise<any> {
      return new Promise<any>((resolve, reject) => {
        procId ? resolve({}) : reject()
      })
    },

    /** 创建流程步骤 */
    createFlowPrco(
      procId: string,
      _userId: string,
      _userName: string,
      _formData: Record<string, any>
    ): Promise<any> {
      return new Promise<any>((resolve, reject) => {
        procId ? resolve({}) : reject()
      })
    },

    /** 获取流程步骤实例信息 */
    getFlowPrcoInsInfo(insId: string) {
      return new Promise<any>((resolve, reject) => {
        insId ? resolve({}) : reject()
      })
    },

    /** 启动流程步骤 (草稿项) */
    startFlowPrco(
      procId: string,
      _insId: string,
      _userId: string,
      _userName: string
    ) {
      return new Promise<any>((resolve, reject) => {
        procId ? resolve({}) : reject()
      })
    },

    /** 获取发起任务列表 */
    getApplyTasks(data: SysProcInstanceAppGetApplyTaskInput) {
      return new Promise<any>((resolve, reject) => {
        data ? resolve(null) : reject()
      })
    },

    /** 获取发起任务信息 */
    getApplyTaskInfo(taskId: string) {
      return new Promise<any>((resolve, reject) => {
        taskId ? resolve({}) : reject()
      })
    },

    /** 提交发起任务信息 */
    submitApplyTask(taskId: string, _userId: string, _userName: string) {
      return new Promise<any>((resolve, reject) => {
        taskId ? resolve({}) : reject()
      })
    },

    /** 删除发起任务信息 */
    delApplyTask(taskId: string, _userId: string, _userName: string) {
      return new Promise<any>((resolve, reject) => {
        taskId ? resolve({}) : reject()
      })
    },

    /** 获取审批任务列表 */
    getApproveTasks(data: SysApproveTaskInput) {
      return new Promise<any>((resolve, reject) => {
        data ? resolve(null) : reject()
      })
    },

    /** 获取审批任务信息 */
    getApproveTaskInfo(taskId: string) {
      return new Promise<any>((resolve, reject) => {
        taskId ? resolve({}) : reject()
      })
    },

    /** 同意审批任务信息 */
    agreeApproveTask(taskId: string, _userId: string, _userName: string) {
      return new Promise<any>((resolve, reject) => {
        taskId ? resolve({}) : reject()
      })
    },

    /** 拒绝审批任务信息 */
    refuseApproveTask(taskId: string, _userId: string, _userName: string) {
      return new Promise<any>((resolve, reject) => {
        taskId ? resolve({}) : reject()
      })
    },

    /** 获取可退回节点 */
    // @ts-ignore
    getCanBackNodes(insId: string, nodeId: string) {
      return new Promise<any>((resolve, reject) => {
        insId ? resolve({}) : reject()
      })
    },

    /** 退回审批任务 */
    backApproveTask(
      taskId: string,
      _nodeIds: Array<string>,
      __userId: string,
      _userName: string
    ) {
      return new Promise<any>((resolve, reject) => {
        taskId ? resolve({}) : reject()
      })
    },

    /** 转交审批任务 */
    deliverApproveTask(data: SysDeliverApproveTaskInput) {
      return new Promise<any>((resolve, reject) => {
        data ? resolve({}) : reject()
      })
    },

    /** 加签审批任务 */
    addSignApproveTask(data: SysAddSignApproveTaskInput) {
      return new Promise<any>((resolve, reject) => {
        data ? resolve({}) : reject()
      })
    },

    /** 收回加签审批任务 */
    takebackAddSignApproveTask(data: SysTakebackAddSignApproveTaskInput) {
      return new Promise<any>((resolve, reject) => {
        data ? resolve({}) : reject()
      })
    },

    /** 审批任务能否收回 */
    approveTaskCanTakeback(taskId: string) {
      return new Promise<boolean>((resolve, reject) => {
        taskId ? resolve(true) : reject()
      })
    },

    /** 获取抄送任务 */
    getCarbonTasks(data: SysCarbonTaskInput) {
      return new Promise<any>((resolve, reject) => {
        data ? resolve(null) : reject()
      })
    },

    /** 获取抄送任务信息 */
    getCarbonTaskInfo(taskId: string) {
      return new Promise<any>((resolve, reject) => {
        taskId ? resolve(null) : reject()
      })
    },

    /** 阅读抄送任务 */
    readCarbonTask(taskId: string, _userId: string, _userName: string) {
      return new Promise<boolean>((resolve, reject) => {
        taskId ? resolve(true) : reject()
      })
    },

    /** 取消阅读抄送任务 */
    unreadCarbonTask(taskId: string, _userId: string, _userName: string) {
      return new Promise<boolean>((resolve, reject) => {
        taskId ? resolve(true) : reject()
      })
    },

    /** 手动办结 */
    manualOver(insId: string, _userId: string, _userName: string) {
      return new Promise<boolean>((resolve, reject) => {
        insId ? resolve(true) : reject()
      })
    },

    /** 中止 */
    terminate(insId: string, _userId: string, _userName: string) {
      return new Promise<boolean>((resolve, reject) => {
        insId ? resolve(true) : reject()
      })
    },

    /** 保存节点变量 */
    saveNodeVariable(
      insId: string,
      _nodeId: string,
      _userId: string,
      _userName: string,
      _formData: Record<string, any>
    ) {
      return new Promise<boolean>((resolve, reject) => {
        insId ? resolve(true) : reject()
      })
    },
  }

  return Object.assign(bwUtils, options)
}
